package com.evanp.pay.controller;

import cn.hutool.core.util.IdUtil;
import com.evanp.pay.config.UnionpayConfig;
import com.evanp.pay.model.UnionPay;
import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.SDKConfig;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

import static com.evanp.pay.util.HttpUtil.getAllRequestParam;

@CrossOrigin
@RestController
@RequestMapping("/unionpay")
public class UnionPayController {
    @Resource
    Logger logger;
    @Resource
    UnionpayConfig unionpayConfig;

    @GetMapping("/snowflake")
    public String getSnowId(){
        return String.valueOf(IdUtil.getSnowflakeNextId());
    }

    @PostMapping("/pay")
    public String doPay(@RequestParam String oid,@RequestParam String money){
        UnionPay unionPay = new UnionPay(oid, money);
        Map<String, String> requestData = unionPay.toMap();
        System.out.println("【------------------打印UnionPay------------------】");
        System.out.println(unionPay);
        System.out.println("【------------------打印UnionPay------------------】");
        System.out.println("【------------------打印requestData<Map>------------------】");
        System.out.println(requestData);
        System.out.println("【------------------打印requestData<Map>------------------】");
        Map<String, String> submitFromData = AcpService.sign(requestData, unionpayConfig.encoding);  //报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。

        String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl();  //获取请求银联的前台地址：对应属性文件acp_sdk.properties文件中的acpsdk.frontTransUrl
        String html = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData,unionpayConfig.encoding);   //生成自动跳转的Html表单
        //将生成的html写到浏览器中完成自动跳转打开银联支付页面；这里调用signData之后，将html写到浏览器跳转到银联页面之前均不能对html中的表单项的名称和值进行修改，如果修改会导致验签不通过
        return html;
    }

    @PostMapping("/callBack")
    public void callBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("callBack接收后台通知开始");

        String encoding = request.getParameter(unionpayConfig.encoding);
        // 获取银联通知服务器发送的后台通知参数
//        Map<String, String> params = new HashMap<>();
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> requestParams = getAllRequestParam(request);
        for (String name : requestParams.keySet()) {
            logger.info(name + " = " + request.getParameter(name));
        }


        //重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
        if (!AcpService.validate(requestParams, encoding)) {
            logger.info("验证签名结果[失败].");
            //验签失败，需解决验签问题

        } else {
            logger.info("验证签名结果[成功].");
            //【注：为了安全验签成功才应该写商户的成功处理逻辑】交易成功，更新商户订单状态

            String orderId =requestParams.get("orderId"); //获取后台通知的数据，其他字段也可用类似方式获取
            String respCode = requestParams.get("respCode");
            //判断respCode=00、A6后，对涉及资金类的交易，请再发起查询接口查询，确定交易成功后更新数据库。

        }
        logger.info("callBack接收后台通知结束");
        //返回给银联服务器http 200  状态码
        response.getWriter().print("ok");
    }
}
